package cn.workreport.modules.users.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.workreport.modules.common.annotations.UserLoginToken;
import cn.workreport.modules.common.controller.BaseController;
import cn.workreport.modules.common.enums.IsEnum;
import cn.workreport.modules.common.po.PagePO;
import cn.workreport.modules.common.vo.PageVO;
import cn.workreport.modules.permission.enums.PermissionEnum;
import cn.workreport.modules.upload.entity.Upload;
import cn.workreport.modules.upload.enums.BusinessKeyEnum;
import cn.workreport.modules.upload.service.IUploadService;
import cn.workreport.modules.users.entity.UserEntity;
import cn.workreport.modules.users.po.UserConfigPO;
import cn.workreport.modules.users.po.UserIdsPO;
import cn.workreport.modules.users.po.UserPO;
import cn.workreport.modules.users.service.IUserService;
import cn.workreport.modules.users.vo.CommonUserVO;
import cn.workreport.modules.users.vo.UserConfigVO;
import cn.workreport.modules.users.vo.UserVO;
import cn.workreport.util.JsonResult;
import cn.workreport.util.PageQueryUtil;
import cn.workreport.util.UserChacheFromToken;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@RestController
@Api(tags = "用户模块")
public class UserController extends BaseController {
    @Autowired
    private IUserService userService;

    @Autowired
    private IUploadService uploadService;

    // 上传文件保存的绝对路径
    @Value("${upload.location}")
    private String uploadLocation;

    /**
     * 普通用户注册
     *
     * @param user
     * @return
     */
    @ApiOperation("普通用户注册")
    @PostMapping("/users/reg")
    public JsonResult<?> reg(UserPO user) {
        System.err.println("======== 进入 /users/reg ========");
        return userService.reg(user);
    }

    /**
     * 登录
     *
     * @param username
     * @param password
     * @return 使用了 @RequestBody 之後只能接受json 格式的參數，這個註解在參數列表只能使用一次
     */
    @ApiOperation("登录")
    @PostMapping("/users/login")
    public JsonResult<?> login(String username, String password, HttpServletRequest request) {
        System.err.println("======== 进入 /users/login ========");
        System.out.println("\tusername ===> " + username);
        System.out.println("\tpassword ===> " + password);
        return userService.login(username, password, request);
    }

    /**
     * 退出登录
     */
    @ApiOperation("退出登录")
    @UserLoginToken
    @GetMapping("/users/logout")
    public JsonResult<?> logout() {
        userService.logout();
        return JsonResult.ok();
    }

    /**
     * 用户修改用户信息
     *
     * @param user
     * @return
     */
    @ApiOperation("用户修改用户信息")
    @UserLoginToken
    @PostMapping("/users/update")
    public JsonResult<?> update(UserPO user) {
        return userService.update(user);
    }

    /**
     * 用户修改用户密码
     *
     * @param
     * @return
     */
    @ApiOperation("用户修改用户密码")
    @UserLoginToken
    @PostMapping("/users/updatePassword")
    public JsonResult<?> updatePassword(String oldPassword, String newPassword) {
        return userService.updatePassword(oldPassword, newPassword);
    }

    /**
     * 用户修改头像
     *
     * @param
     * @return
     */
    @ApiOperation("用户修改头像")
    @UserLoginToken
    @PostMapping("/users/updateAvatar")
    public JsonResult<?> updateAvatar(String avatarBase64Str, HttpSession session) {
        if (StrUtil.isBlank(avatarBase64Str)) {
            return JsonResult.fail("参数 avatarBase64Str 不能为空");
        }
        // 自定义配置文件目标保存位置路径
        String realPath = uploadLocation;
        // 保存文件的文件夹名称（按日期分类文件夹）
        String fileDir = "images/avatar/" + DateUtil.format(new Date(), "yyyy-MM-dd");
        // 文件后缀
        String suffix = ".jpeg";
        // 解析base64成文件，压缩并保存文件，返回保存信息对象
        Upload uploadEntity = uploadService.base64TransferImgEntity(avatarBase64Str, realPath, fileDir, suffix, BusinessKeyEnum.AVATAR);
        log.info("uploadEntity ===>" + uploadEntity);
        if (ObjectUtils.isEmpty(uploadEntity)) {
            return JsonResult.fail("上传失败，请稍后重试");
        }
        // 限制文件上传的大小（一般也就几十k）
        if (!ObjectUtils.isEmpty(uploadEntity.getFileSize()) && uploadEntity.getFileSize() > 200 * 1024) {
            return JsonResult.fail("上传头像不能大于200KB");
        }
        // --------------------------- 限制用户当天上传的次数 start ---------------------
        // 取出当前登录用户信息
//        UserEntity currentLoginUser = UserChacheFromToken.getUser();
//        LambdaQueryWrapper<Upload> wrapper = new LambdaQueryWrapper<>();
//        Date startDateTime = DateUtil.beginOfDay(new Date());
//        Date endDateTime = DateUtil.endOfDay(new Date());
//        log.info("startDateTime ===>" + startDateTime);
//        log.info("endDateTime ===>" + endDateTime);
//        wrapper.eq(Upload::getCreatorId, currentLoginUser.getId());
//        wrapper.ge(ObjectUtil.isNotNull(startDateTime), Upload::getCreatedTime, startDateTime);
//        wrapper.le(ObjectUtil.isNotNull(endDateTime), Upload::getCreatedTime, endDateTime);
//        wrapper.orderByAsc(Upload::getCreatedTime);
//        int hasCount = uploadService.count(wrapper);
//        log.info("hasCount ===>" + hasCount);
//        // 限制当天只能传10张
//        if (hasCount >= 6) {
//            return JsonResult.fail("一天上传次数只能6次哦");
//        }
        // --------------------------- 限制用户当天上传的次数 end ---------------------
        // 保存新文件信息到文件记录表
        boolean isSuccess = uploadService.saveOrUpdate(uploadEntity);
        if (!isSuccess) {
            return JsonResult.fail("文件记录操作失败");
        }
        // 取出当前登录用户信息
        UserEntity currentLoginUser = UserChacheFromToken.getUser();
        // 用户的旧头像的相对路径
        String oldFilePath = currentLoginUser.getAvatar();
        if (StrUtil.isNotEmpty(oldFilePath)) {
            // 找到该用户的旧头像，删除该文件
            LambdaQueryWrapper<Upload> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Upload::getFilePath, oldFilePath);
            Upload oldUploadEntity = uploadService.getOne(wrapper);
            if (ObjectUtil.isNotEmpty(oldUploadEntity) && StrUtil.isNotEmpty(oldUploadEntity.getFileLocation())) {
                try {
                    boolean isDeleteSuccess = FileUtil.del(oldUploadEntity.getFileLocation());
                    log.info("旧文件是否删除成功 ====> isDeleteSuccess =" + isDeleteSuccess);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        // 执行修改用户头像信息
        return userService.updateAvatar(uploadEntity.getFilePath());
    }

    /**
     * 查询所有用户列表（不显示敏感信息）
     */
    @ApiOperation("查询所有用户列表（不显示敏感信息）")
    @UserLoginToken
    @PostMapping("/users/listPage")
    public JsonResult<?> listPage(PagePO<UserEntity> pagePO) {
        log.info("===> 进入 /users/listPage ===> params = " + pagePO);
        IPage<UserEntity> page = new PageQueryUtil<UserEntity>().getPage(pagePO);
        LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.orderByDesc(UserEntity::getCreatedTime);
        PageVO<UserEntity> result = userService.pageEntity(page, wrapper);
        List<CommonUserVO> userVOList = result.getList().stream().map(userEntity -> {
            CommonUserVO userVO = new CommonUserVO();
            BeanUtil.copyProperties(
                    userEntity,
                    userVO,
                    // 复制旧的属性过来，忽略null属性，忽略null值，有值的以新的为主，null的则以旧为主
                    CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true)
            );
            return userVO;
        }).collect(Collectors.toList());
        PageVO<CommonUserVO> newResult = new PageVO<>(userVOList, result.getTotal(), result.getSize(), result.getCurrent());
        return JsonResult.ok(newResult);
    }

    /**
     * 管理员查询所有用户列表（显示所有信息）
     */
    @ApiOperation("管理员查询所有用户列表（显示所有信息）")
    @UserLoginToken(permission = {PermissionEnum.USERS_PAGE})
    @PostMapping("/users/listPageByAdmin")
    public JsonResult<?> listPageByAdmin(@RequestBody PagePO<UserEntity> pagePO) {
        log.info("===> 进入 /users/listPageByAdmin ===> params: pagePO=" + pagePO);
        // 如果不是超级管理员，必须要传 orgId
        UserEntity loginUser = UserChacheFromToken.getUser();
        UserEntity condition = pagePO.getCondition();
        if (
                (ObjectUtil.isEmpty(loginUser.getIsSupperAdmin()) || !loginUser.getIsSupperAdmin())
                        && (ObjectUtil.isEmpty(condition) || ObjectUtil.isEmpty(condition.getOrgId()))
        ) {
            return JsonResult.fail("参数 orgId 不能为空");
        }
        // 执行查询
        IPage<UserEntity> page = new PageQueryUtil<UserEntity>().getPage(pagePO);
        LambdaQueryWrapper<UserEntity> wrapper = new LambdaQueryWrapper<>();
        if (!ObjectUtils.isEmpty(condition)) {
            wrapper.like(!ObjectUtils.isEmpty(condition.getUsername()), UserEntity::getUsername, condition.getUsername());
            wrapper.like(!ObjectUtils.isEmpty(condition.getNickname()), UserEntity::getNickname, condition.getNickname());
            wrapper.like(!ObjectUtils.isEmpty(condition.getTruename()), UserEntity::getTruename, condition.getTruename());
            wrapper.like(!ObjectUtils.isEmpty(condition.getPhone()), UserEntity::getPhone, condition.getPhone());
            wrapper.eq(!ObjectUtils.isEmpty(condition.getDeleted()), UserEntity::getDeleted, condition.getDeleted());
            wrapper.eq(!ObjectUtils.isEmpty(condition.getGroupId()), UserEntity::getGroupId, condition.getGroupId());
            wrapper.eq(!ObjectUtils.isEmpty(condition.getOrgId()), UserEntity::getOrgId, condition.getOrgId());
        }
        wrapper.orderByDesc(UserEntity::getCreatedTime);
        PageVO<UserEntity> result = userService.pageEntity(page, wrapper);
        return JsonResult.ok(result);
    }

    /**
     * 管理员注册用户
     *
     * @param user
     * @return
     */
    @ApiOperation("管理员注册用户")
    @UserLoginToken(permission = {PermissionEnum.USERS_REG_BY_ADMIN})
    @PostMapping("/users/regByAdmin")
    public JsonResult<?> regByAdmin(UserPO user) {
        System.err.println("======== 进入 /users/regByAdmin ========");
        return userService.regByAdmin(user);
    }

    /**
     * 管理员修改用户信息
     *
     * @param user
     * @return
     */
    @ApiOperation("管理员修改用户信息")
    @UserLoginToken(permission = {PermissionEnum.USERS_UPDATE_BY_ADMIN})
    @PostMapping("/users/updateByAdmin")
    public JsonResult<?> updateByAdmin(UserPO user) {
        System.err.println("======== 进入 /users/updateByAdmin ========");
        return userService.updateByAdmin(user);
    }

    /**
     * 管理员修改用户角色
     *
     * @param userId
     * @param roleId
     * @return
     */
    @ApiOperation("管理员修改用户角色")
    @UserLoginToken(permission = {PermissionEnum.USERS_UPDATE_ROLE_BY_ADMIN})
    @PostMapping("/users/updateRoleByAdmin")
    public JsonResult<?> updateRoleByAdmin(Integer userId, Integer roleId) {
        System.err.println("======== 进入 /users/updateRoleByAdminupdateRoleByAdmin ========");
        return userService.updateRoleByAdmin(userId, roleId);
    }

    /**
     * 管理员修改用户密码
     *
     * @param userId
     * @param newPassword
     * @return
     */
    @ApiOperation("管理员修改用户重置密码")
    @UserLoginToken(permission = {PermissionEnum.USERS_UPDATE_PW_BY_ADMIN})
    @PostMapping("/users/updatePasswordByAdmin")
    public JsonResult<?> updatePasswordByAdmin(Integer userId, String newPassword) {
        System.err.println("======== 进入 /users/updatePasswordByAdmin ========");
        return userService.updatePasswordByAdmin(userId, newPassword);
    }

    /**
     * 管理员修改用户停用状态
     *
     * @param userId
     * @param deleted
     * @return
     */
    @ApiOperation("管理员修改用户停用状态")
    @UserLoginToken(permission = {PermissionEnum.USERS_UPDATE_STATUS_BY_ADMIN})
    @PostMapping("/users/toggleDeletedByAdmin")
    public JsonResult<?> toggleDeletedByAdmin(Integer userId, IsEnum deleted) {
        System.err.println("======== 进入 /users/toggleDeletedByAdmin ========");
        return userService.toggleDeletedByAdmin(userId, deleted);
    }

    /**
     * 修改添加组织成员（废弃）
     *
     * @param userIdsPO 用户 id 数组
     * @param groupId   组织的 id
     * @return
     */
    @ApiOperation("修改添加组织成员")
    @UserLoginToken(required = true, permission = {PermissionEnum.USERS_UPDATE_GROUP})
    @PostMapping("/users/updateUsersGroup")
    public JsonResult<?> updateUsersGroup(UserIdsPO userIdsPO, Integer groupId, Integer leaderId, Integer orgId) {
        System.err.println("======== 进入 /users/editUserGroup ======== param: userIdsPO = " + userIdsPO + "; groupId = " + groupId + "; leaderId = " + leaderId + "; orgId=" + orgId);
        return userService.updateUsersGroup(userIdsPO.getUserIds(), groupId, leaderId, orgId);
    }

    /**
     * 添加组织成员
     *
     * @param userId  用户 id
     * @param groupId 组织的 id
     * @return
     */
    @ApiOperation("添加组织成员")
    @UserLoginToken(permission = {PermissionEnum.USERS_UPDATE_GROUP})
    @PostMapping("/users/userBindGroup")
    public JsonResult<?> userBindGroup(Integer userId, Integer groupId) {
        System.err.println("======== 进入 /users/userBindGroup ======== param: userId = " + userId + "; groupId = " + groupId);
        return userService.userBindGroup(userId, groupId);
    }

    /**
     * 查询组织成员
     *
     * @param groupId 组织的 id
     * @return
     */
    @ApiOperation("查询组织成员")
    @UserLoginToken
    @GetMapping("/users/listUserByGroupId")
    public JsonResult<?> listUserByGroupId(Integer groupId) {
        System.err.println("======== 进入 /users/listUserByGroupId ======== param: groupId = " + groupId);
        if (ObjectUtil.isEmpty(groupId)) {
            return JsonResult.fail("缺少参数 groupId");
        }
        List<UserEntity> userList = userService.getUserListByGroupId(groupId);
        return JsonResult.ok(userList);
    }

    /**
     * 删除组织成员
     *
     * @param userId 用户 id
     * @return
     */
    @ApiOperation("删除组织成员")
    @UserLoginToken(permission = {PermissionEnum.USERS_UPDATE_GROUP})
    @PostMapping("/users/userUnboundGroup")
    public JsonResult<?> userUnboundGroup(Integer userId) {
        System.err.println("======== 进入 /users/userUnboundGroup ======== param: userId = " + userId);
        return userService.userUnboundGroup(userId);
    }

    /**
     * 设置组织管理员
     *
     * @param userId 用户 id
     * @return
     */
    @ApiOperation("设置组织管理员")
    @UserLoginToken(permission = {PermissionEnum.USERS_UPDATE_GROUP})
    @PostMapping("/users/setGroupManager")
    public JsonResult<?> setGroupManager(Integer userId) {
        System.err.println("======== 进入 /users/setGroupManager ======== param: userId = " + userId);
        return userService.setGroupManager(userId);
    }

    /**
     * 查询获取没有组织的用户列表
     */
    @ApiOperation("查询获取没有组织的用户列表")
    @UserLoginToken
    @PostMapping("/users/listHasNotGroupUser")
    public JsonResult<?> listHasNotGroupUser(Integer orgId) {
        log.info("===> 进入 /users/hasNoGroupListPage ===> params: orgId=" + orgId);
        return userService.listHasNotGroupUser(orgId);
    }

    /**
     * 当前登录用户关联机构
     *
     * @param orgId 机构id
     * @return JsonResult
     */
    @ApiOperation("当前登录用户关联机构")
    @UserLoginToken
    @PostMapping("/users/userBindOrg")
    public JsonResult<?> userBindOrg(Integer orgId, String verifyAnswer) {
        System.err.println("进入 /users/userBindOrg === param: orgId=" + orgId + "; verifyAnswer=" + verifyAnswer);
        if (ObjectUtil.isEmpty(orgId)) {
            return JsonResult.fail("缺少参数 orgId");
        }
        return userService.userBindOrg(orgId, verifyAnswer);
    }

    /**
     * 当前登录用户解除关联的机构
     *
     * @param orgId 机构id
     * @return JsonResult
     */
    @ApiOperation("当前登录用户解除关联的机构")
    @UserLoginToken
    @PostMapping("/users/userUnboundOrg")
    public JsonResult<?> userUnboundOrg(Integer orgId) {
        System.err.println("进入 /users/userUnboundOrg === param: orgId=" + orgId);
        if (ObjectUtil.isEmpty(orgId)) {
            return JsonResult.fail("缺少参数 orgId");
        }
        return userService.userUnboundOrg(orgId);
    }

    /**
     * 用户列表预加载数据
     *
     * @return JsonResult
     */
    @ApiOperation("用户列表预加载数据")
    @GetMapping("/users/preparedData")
    public JsonResult<?> preparedData() {
        log.info("===> 进入 /users/preparedData ===> ");
        return userService.preparedData();
    }

    /**
     * 根据ID查询用户
     * 如果查询不到，new 一个返回，可以作为新建请求
     *
     * @param id ID
     * @return 查询结果
     */
    @ApiOperation("根据ID查询用户")
    @GetMapping("/users/getById")
    public JsonResult<?> getById(Integer id) {
        log.info("===> 进入 /users/getById ===> params: id" + id);
        if (ObjectUtils.isEmpty(id)) {
            return JsonResult.fail("参数 id 不能为空！");
        }
        UserEntity entity = this.userService.getByIdEntity(id);
        UserVO userVO = this.userService.getVoByEntity(entity);
        return JsonResult.ok(userVO);
    }

    /**
     * 获取用户配置信息
     *
     * @return 查询结果
     */
    @ApiOperation("获取用户配置信息")
    @UserLoginToken
    @GetMapping("/users/getUserConfig")
    public JsonResult<?> getUserConfig() {
        log.info("===> 进入 /users/getUserConfig ===> ");
        UserEntity entity = UserChacheFromToken.getUser();
        UserConfigVO result = new UserConfigVO();
        BeanUtil.copyProperties(entity, result, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        result.setUserId(entity.getId());
        return JsonResult.ok(result);
    }

    /**
     * 设置用户配置信息
     *
     * @return 查询结果
     */
    @ApiOperation("设置用户配置信息")
    @UserLoginToken
    @PostMapping("/users/setUserConfig")
    public JsonResult<?> setUserConfig(UserConfigPO params) {
        log.info("===> 进入 /users/setUserConfig ===> params: " + params);
        UserEntity entity = UserChacheFromToken.getUser();
        BeanUtil.copyProperties(params, entity, CopyOptions.create().setIgnoreNullValue(true).setIgnoreError(true));
        if (!this.userService.saveOrUpdate(entity)) {
            return JsonResult.fail();
        }
        return JsonResult.ok();
    }

    /**
     * 根据组长id，查询组员
     */
    @ApiOperation("根据组长id，查询组员")
    @UserLoginToken
    @GetMapping("/users/getMembersByLeaderId")
    public JsonResult<?> getMembersByLeaderId(Integer id) {
        log.info("===> 进入 /users/getMembersByLeaderId ===> params: id" + id);
        if (ObjectUtils.isEmpty(id)) {
            return JsonResult.fail("参数 id 不能为空！");
        }
        List<UserEntity> userList = userService.getMembersByLeaderId(id);
        return JsonResult.ok(userList);
    }
}
